﻿using System;
using System.ComponentModel;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using Model.Interfaces;
using Model.ModelClasses;
using Model.ModelEventArgs;

namespace Data.MappingClasses
{
    [TableAttribute(Name = "dbo.[Group]")]
    public partial class Group : AbstractMappingClass, INotifyPropertyChanging, INotifyPropertyChanged
    {

        public event EventHandler<ModelItemEventArgs> AddedStudentEvent;
        public event EventHandler<ModelItemEventArgs> RemovedStudentEvent;

        private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);

        private short _idGroup;

        private short _refTeacherSubject;

        private short _refSubdivision;

        private System.Nullable<System.DateTime> _beginDate;

        private System.Nullable<System.DateTime> _endDate;

        private string _groupName;

        private EntitySet<Lesson> _Lessons;

        private EntitySet<StudentGroup> _StudentGroups;

        private EntityRef<Subdivision> _Subdivision;

        private EntityRef<TeacherSubject> _TeacherSubject;

        #region Extensibility Method Definitions
        partial void OnLoaded();
        partial void OnValidate(System.Data.Linq.ChangeAction action);
        partial void OnCreated();
        partial void OnidGroupChanging(short value);
        partial void OnidGroupChanged();
        partial void OnrefTeacherSubjectChanging(short value);
        partial void OnrefTeacherSubjectChanged();
        partial void OnrefSubdivisionChanging(short value);
        partial void OnrefSubdivisionChanged();
        partial void OnbeginDateChanging(System.Nullable<System.DateTime> value);
        partial void OnbeginDateChanged();
        partial void OnendDateChanging(System.Nullable<System.DateTime> value);
        partial void OnendDateChanged();
        partial void OngroupNameChanging(string value);
        partial void OngroupNameChanged();
        #endregion

        public Group()
        {
            this._Lessons = new EntitySet<Lesson>(new Action<Lesson>(this.AttachLessons), new Action<Lesson>(this.DetachLessons));
            this._StudentGroups = new EntitySet<StudentGroup>(new Action<StudentGroup>(this.AttachStudentGroups), new Action<StudentGroup>(this.DetachStudentGroups));
            this._Subdivision = default(EntityRef<Subdivision>);
            this._TeacherSubject = default(EntityRef<TeacherSubject>);
            OnCreated();
        }

        [ColumnAttribute(Storage = "_idGroup", AutoSync = AutoSync.OnInsert, DbType = "SmallInt NOT NULL IDENTITY", IsPrimaryKey = true, IsDbGenerated = true)]
        public short idGroup
        {
            get
            {
                return this._idGroup;
            }
            set
            {
                if ((this._idGroup != value))
                {
                    this.OnidGroupChanging(value);
                    this.SendPropertyChanging();
                    this._idGroup = value;
                    this.SendPropertyChanged("idGroup");
                    this.OnidGroupChanged();
                }
            }
        }

        [global::System.Data.Linq.Mapping.ColumnAttribute(Storage = "_refTeacherSubject", DbType = "SmallInt NOT NULL")]
        public short refTeacherSubject
        {
            get
            {
                return this._refTeacherSubject;
            }
            set
            {
                if ((this._refTeacherSubject != value))
                {
                    if (this._TeacherSubject.HasLoadedOrAssignedValue)
                    {
                        throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
                    }
                    this.OnrefTeacherSubjectChanging(value);
                    this.SendPropertyChanging();
                    this._refTeacherSubject = value;
                    this.SendPropertyChanged("refTeacherSubject");
                    this.OnrefTeacherSubjectChanged();
                }
            }
        }

        [global::System.Data.Linq.Mapping.ColumnAttribute(Storage = "_refSubdivision", DbType = "SmallInt NOT NULL")]
        public short refSubdivision
        {
            get
            {
                return this._refSubdivision;
            }
            set
            {
                if ((this._refSubdivision != value))
                {
                    if (this._Subdivision.HasLoadedOrAssignedValue)
                    {
                        throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
                    }
                    this.OnrefSubdivisionChanging(value);
                    this.SendPropertyChanging();
                    this._refSubdivision = value;
                    this.SendPropertyChanged("refSubdivision");
                    this.OnrefSubdivisionChanged();
                }
            }
        }

        [global::System.Data.Linq.Mapping.ColumnAttribute(Storage = "_beginDate", DbType = "DateTime")]
        public System.Nullable<System.DateTime> beginDate
        {
            get
            {
                return this._beginDate;
            }
            set
            {
                if ((this._beginDate != value))
                {
                    this.OnbeginDateChanging(value);
                    this.SendPropertyChanging();
                    this._beginDate = value;
                    this.SendPropertyChanged("beginDate");
                    this.OnbeginDateChanged();
                }
            }
        }

        [global::System.Data.Linq.Mapping.ColumnAttribute(Storage = "_endDate", DbType = "DateTime")]
        public System.Nullable<System.DateTime> endDate
        {
            get
            {
                return this._endDate;
            }
            set
            {
                if ((this._endDate != value))
                {
                    this.OnendDateChanging(value);
                    this.SendPropertyChanging();
                    this._endDate = value;
                    this.SendPropertyChanged("endDate");
                    this.OnendDateChanged();
                }
            }
        }

        [global::System.Data.Linq.Mapping.ColumnAttribute(Storage = "_groupName", DbType = "VarChar(15)")]
        public string groupName
        {
            get
            {
                return this._groupName;
            }
            set
            {
                if ((this._groupName != value))
                {
                    this.OngroupNameChanging(value);
                    this.SendPropertyChanging();
                    this._groupName = value;
                    this.SendPropertyChanged("groupName");
                    this.OngroupNameChanged();
                }
            }
        }

        [global::System.Data.Linq.Mapping.AssociationAttribute(Name = "Group_Lesson", Storage = "_Lessons", ThisKey = "idGroup", OtherKey = "refGroup")]
        public EntitySet<Lesson> Lessons
        {
            get
            {
                return this._Lessons;
            }
            set
            {
                this._Lessons.Assign(value);
            }
        }

        [global::System.Data.Linq.Mapping.AssociationAttribute(Name = "Group_StudentGroup", Storage = "_StudentGroups", ThisKey = "idGroup", OtherKey = "refGroup")]
        public EntitySet<StudentGroup> StudentGroups
        {
            get
            {
                return this._StudentGroups;
            }
            set
            {
                this._StudentGroups.Assign(value);
            }
        }

        [global::System.Data.Linq.Mapping.AssociationAttribute(Name = "Subdivision_Group", Storage = "_Subdivision", ThisKey = "refSubdivision", OtherKey = "idSubdivision", IsForeignKey = true)]
        public Subdivision Subdivision
        {
            get
            {
                return this._Subdivision.Entity;
            }
            set
            {
                Subdivision previousValue = this._Subdivision.Entity;
                if (((previousValue != value)
                     || (this._Subdivision.HasLoadedOrAssignedValue == false)))
                {
                    this.SendPropertyChanging();
                    if ((previousValue != null))
                    {
                        this._Subdivision.Entity = null;
                        previousValue.Groups.Remove(this);
                    }
                    this._Subdivision.Entity = value;
                    if ((value != null))
                    {
                        value.Groups.Add(this);
                        this._refSubdivision = value.idSubdivision;
                    }
                    else
                    {
                        this._refSubdivision = default(short);
                    }
                    this.SendPropertyChanged("Subdivision");
                }
            }
        }

        [global::System.Data.Linq.Mapping.AssociationAttribute(Name = "TeacherSubject_Group", Storage = "_TeacherSubject", ThisKey = "refTeacherSubject", OtherKey = "idTeacherSubject", IsForeignKey = true)]
        public TeacherSubject TeacherSubject
        {
            get
            {
                return this._TeacherSubject.Entity;
            }
            set
            {
                TeacherSubject previousValue = this._TeacherSubject.Entity;
                if (((previousValue != value)
                     || (this._TeacherSubject.HasLoadedOrAssignedValue == false)))
                {
                    this.SendPropertyChanging();
                    if ((previousValue != null))
                    {
                        this._TeacherSubject.Entity = null;
                        previousValue.Groups.Remove(this);
                    }
                    this._TeacherSubject.Entity = value;
                    if ((value != null))
                    {
                        value.Groups.Add(this);
                        this._refTeacherSubject = value.idTeacherSubject;
                    }
                    else
                    {
                        this._refTeacherSubject = default(short);
                    }
                    this.SendPropertyChanged("TeacherSubject");
                }
            }
        }

        public event PropertyChangingEventHandler PropertyChanging;

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void SendPropertyChanging()
        {
            if ((this.PropertyChanging != null))
            {
                this.PropertyChanging(this, emptyChangingEventArgs);
            }
        }

        protected virtual void SendPropertyChanged(String propertyName)
        {
            if ((this.PropertyChanged != null))
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        private void AttachLessons(Lesson entity)
        {
            this.SendPropertyChanging();
            entity.Group = this;
        }

        private void DetachLessons(Lesson entity)
        {
            this.SendPropertyChanging();
            entity.Group = null;
        }

        private void AttachStudentGroups(StudentGroup entity)
        {
            this.SendPropertyChanging();
            entity.Group = this;
        }

        private void DetachStudentGroups(StudentGroup entity)
        {
            this.SendPropertyChanging();
            entity.Group = null;
        }

        public override AbstractModel PureModel
        {
            get
            {
                return base.PureModel;
            }
            set
            {
                if(_pureModel != null)
                {
                    _pureModel.UpdateModelEvent -= UpdateModelEventHandler;
                    ((IGroup) _pureModel).Students.AddedItemEvent -= AddedStudentEventHandler;
                    ((IGroup)_pureModel).Students.RemovedItemEvent -= RemovedStudentEventHandler;
                }

                if(value != null)
                {
                    value.UpdateModelEvent += UpdateModelEventHandler;
                    ((IGroup)value).Students.AddedItemEvent += AddedStudentEventHandler;
                    ((IGroup)value).Students.RemovedItemEvent += RemovedStudentEventHandler;
                }
            }
        }

        private void RemovedStudentEventHandler(object sender, ModelItemEventArgs e)
        {
            if (RemovedStudentEvent != null)
                RemovedStudentEvent(this, e);
        }

        private void AddedStudentEventHandler(object sender, ModelItemEventArgs e)
        {
            if (AddedStudentEvent != null)
                AddedStudentEvent(this, e);
        }

        private void UpdateModelEventHandler(object sender, EventArgs e)
        {
            groupName = ((IGroup) sender).Name;
            beginDate = ((IGroup) sender).BeginDate;
            endDate = ((IGroup)sender).EndDate;
            UpdateData();
        }
    }
}